package com.ap.core.dao;

import com.ap.core.domain.Identifiable;
import com.ap.core.domain.sequence.generation.MultiIdGenerationService;
import org.hibernate.Session;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * User: Ranjit.Singh
 * Base JPA Class for all DAOs.
 * 
 * @param <T>
 *            generic type for the persistent entity
 * @param <U>
 *            generic type for the primary key of the entity
 */
public abstract class AbstractAPCoreBaseJpaDao<T extends Identifiable<U>, U> implements GenericDao<T, U> {

    /** Entity Manager */
    protected EntityManager entityManager;

    private MultiIdGenerationService<U> idGenerationService;

    /**
     * Sets the entity manager.
     * 
     * @param pEntityManager
     *            the new entity manager
     */
    @PersistenceContext(unitName="ap-core")
    protected void setEntityManager(final EntityManager pEntityManager) {
        this.entityManager = pEntityManager;
    }


    public T merge(final T object) {
        return entityManager.merge(object);
    }


    @Override
    public void persist(final T entity) {
        if(null == entity.getId()){
            entity.setId(idGenerationService.getNextId(entity.getClass()));
        }
         entityManager.persist(entity);
    }


    @Override
    public void flush() {
        entityManager.flush();
    }


    @Override
    public void clear() {
        entityManager.clear();
    }

    /**
     * Find entity instance by id.
     * 
     * @param entityClass
     *            the entity class
     * @param primaryKey
     *            primary key for the entity
     * @return the found instance of the entity class
     */
    protected T findById(final Class<T> entityClass, final U primaryKey) {
        return entityManager.find(entityClass, primaryKey);
    }

    public Session getSession() {
        return (Session) entityManager.getDelegate();
    }

    public void setIdGenerationService(MultiIdGenerationService idGenerationService) {
        this.idGenerationService = idGenerationService;
    }

}